﻿using Furion.DatabaseAccessor;
using Furion.DatabaseAccessor.Extensions;
using Furion.DataEncryption;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using LimaLims.Application.Service.Base.Dto;
using LimaLims.Application.Service.Cache;
using LimaLims.Application.Service.Role;
using LimaLims.Application.Service.User.Dto;
using LimaLims.Core;
using LimaLims.Core.Entity.System;
using LimaLims.Core.Enum;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace LimaLims.Application.Service.User
{
    /// <summary>
    /// 用户服务
    /// </summary>
    [ApiDescriptionSettings(Name = "User", Order = 10)]
    [Route("api")]
    public class SysUserService : ISysUserService, IDynamicApiController, ITransient
    {
        private readonly IRepository<SysUser> _sysUserRep;
        private readonly ISysCacheService _sysCacheService;
        private readonly ISysUserRoleService _sysUserRoleService;
        /// <summary>
        /// 用户服务构造函数
        /// </summary>
        public SysUserService(IRepository<SysUser> sysUserRep, ISysCacheService sysCacheService, ISysUserRoleService sysUserRoleService)
        {
            _sysUserRep = sysUserRep;
            _sysCacheService = sysCacheService;
            _sysUserRoleService = sysUserRoleService;
        }
        /// <summary>
        /// 增加用户
        /// </summary>
        [UnitOfWork]
        [HttpPost("sysUser/add")]
        public async Task AddUser(AddUserInput input)
        {
            var isExist = await _sysUserRep.AnyAsync(u => u.Account == input.Account, false, true);
            if (isExist) throw Oops.Oh("账号已存在");
            var user = input.Adapt<SysUser>();
            user.Password = MD5Encryption.Encrypt(input.Password);
            if (string.IsNullOrEmpty(user.Name))
                user.Name = user.Account;
            var newUser = await _sysUserRep.InsertNowAsync(user);
            input.Id = newUser.Entity.Id;
            if (input.RoleIdList.Any() && input.RoleIdList.Count > 0)
            {
                await this.GrantUserRole(new UpdateUserRoleDataInput { Id = input.Id, GrantRoleIdList = input.RoleIdList });
            }
        }

        /// <summary>
        /// 更新用户
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [UnitOfWork]
        [HttpPost("sysUser/edit")]
        public async Task UpdateUser(UpdateUserInput input)
        {
            // 排除自己并且判断与其他是否相同
            var isExist = await _sysUserRep.AnyAsync(u => u.Account == input.Account && u.Id != input.Id, false);
            if (isExist) throw Oops.Oh("账号已存在");

            var user = input.Adapt<SysUser>();
            await user.UpdateExcludeAsync(new[] { nameof(SysUser.Password) }, true);
            await this.GrantUserRole(new UpdateUserRoleDataInput { Id = input.Id, GrantRoleIdList = input.RoleIdList });
        }
        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [UnitOfWork]
        [HttpPost("sysUser/delete")]
        public async Task DeleteUser(long id)
        {
            var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Id == id, false);
            if (user == null)
                throw Oops.Oh("记录不存在");

            if (user.AdminType == AdminType.SuperAdmin)
                throw Oops.Oh("禁止删除超级管理员");

            if (user.AdminType == AdminType.Admin)
                throw Oops.Oh("禁止删除管理员");

            if (user.Id == CurrentUserInfo.UserId)
                throw Oops.Oh("非法操作，禁止删除自己");

            // 直接删除用户
            await user.DeleteAsync();
            //删除该用户对应的用户-角色表关联信息
            await _sysUserRoleService.DeleteUserRoleListByUserId(id);
        }

        /// <summary>
        /// 根据用户Id获取用户
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        [NonAction]
        public async Task<SysUser> GetUserById(long userId)
        {
            return await _sysUserRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == userId);
        }

        /// <summary>
        /// 获取当前用户信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("sysUser/GetCurrentUser")]
        public async Task<UserOutput> GetCurrentUser()
        {
            var user = await _sysUserRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == CurrentUserInfo.UserId);
            return user.Adapt<UserOutput>();
        }

        /// <summary>
        /// 获取用户下拉数据
        /// </summary>
        /// <returns></returns>
        [HttpGet("sysUser/selectList")]
        public async Task<List<SelectDto>> SelectList()
        {
            var list = await _sysUserRep.DetachedEntities.Where(s => s.ValidStatus && s.AdminType!=AdminType.SuperAdmin).OrderBy(s => s.Sort).ToListAsync();
            return list.Select(x => new SelectDto
            {
                Value = x.Id,
                Label = x.Name
            }).ToList();
        }

        /// <summary>
        /// 修改用户基本信息
        /// </summary>
        /// <returns></returns>
        [HttpPost("sysUser/UpdateUsreBase")]
        public async Task UpdateUsreBase(UpdateUsreBase userForm)
        {
            if (userForm.Id != CurrentUserInfo.UserId) throw Oops.Oh("参数有误，与当前用户不符");

            var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Id == userForm.Id, false);

            if (user == null) throw Oops.Oh("用户数据不存在");

            user.Name = userForm.Name;
            //user.Avatar = userForm.Avatar;
            user.Phone = userForm.Phone;
            user.Birthday = userForm.Birthday;
            user.Email = userForm.Email;
            user.Sex = userForm.Sex;

            await _sysUserRep.UpdateAsync(user);
        }

        /// <summary>
        /// 获取用户拥有角色
        /// </summary>
        /// <returns></returns>
        [HttpGet("sysUser/ownRole")]
        public async Task<List<long>> GetUserOwnRole(long userId)
        {
            return await _sysUserRoleService.GetUserRoleIdList(userId);
        }

        /// <summary>
        /// 授权用户角色
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("sysUser/grantRole")]
        public async Task GrantUserRole(UpdateUserRoleDataInput input)
        {
            var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Id == input.Id);
            if (user.AdminType == AdminType.SuperAdmin)
                throw Oops.Oh("禁止为超级管理员分配角色");

            if (user.AdminType == AdminType.Admin)
                throw Oops.Oh("禁止为管理员分配角色");

            await _sysUserRoleService.GrantRole(input);

            //删除权限,重新加载
            await _sysCacheService.RemovePermission(input.Id);
        }

        /// <summary>
        /// 分页查询用户
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("sysUser/page")]
        public async Task<PageResult<UserOutput>> QueryUserPageList(UserInput input)
        {
            var users = await _sysUserRep.DetachedEntities.Include(s => s.Team)
                                         .Where(!string.IsNullOrEmpty(input.Account), x => x.Account.Contains(input.Account))
                                         .Where(!string.IsNullOrEmpty(input.Phone), x => x.Phone.Contains(input.Phone))
                                          .Where((input.TeamId.HasValue, x => x.TeamId == input.TeamId))
                                         .Where(x => x.AdminType != AdminType.SuperAdmin)//排除超级管理员
                                         .Where(s => s.ValidStatus)
                                         .Select(u => new UserOutput
                                         {
                                             Id = u.Id,
                                             Name = u.Name,
                                             TeamId = u.TeamId,
                                             TeamName = u.Team.WorkName + '-' + u.Team.Name,
                                             Account = u.Account,
                                             Avatar = u.Avatar,
                                             Birthday = u.Birthday,
                                             Sex = u.Sex,
                                             Email = u.Email,
                                             Phone = u.Phone,
                                             Tel = u.Tel,
                                             AdminType = u.AdminType,
                                             UpdatedTime = u.UpdatedTime,
                                         }).ToADPagedListAsync(input.PageNo, input.PageSize);

            return users;
        }

        /// <summary>
        /// 重置用户密码
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("sysUser/resetPwd")]
        public async Task ResetUserPwd(long userId)
        {
            var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Id == userId);
            user.Password = MD5Encryption.Encrypt(CommonConst.DEFAULT_PASSWORD);
            await _sysUserRep.UpdateIncludeAsync(user, new[] { nameof(SysUser.Password) }, true);
        }

        /// <summary>
        /// 修改用户密码
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("sysUser/updatePwd")]
        public async Task UpdateUserPwd(ChangePasswordUserInput input)
        {
            var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Id == input.Id);
            if (MD5Encryption.Encrypt(input.Password) != user.Password)
                throw Oops.Oh("当前密码输入错误");
            user.Password = MD5Encryption.Encrypt(input.NewPassword);
            await _sysUserRep.UpdateIncludeAsync(user, new[] { nameof(SysUser.Password) }, true);
        }
    }
}
